//
//  UIView+Frame.swift
//  CzzSwTest
//
//  Created by 陈钟 on 2018/9/21.
//  Copyright © 2018年 陈钟. All rights reserved.
//

import Foundation
import UIKit

public extension UIView{
    @objc enum UIViewLineAlignment : NSInteger {
        case Top,Left,Bottom,Right
    }
    
    @objc var x: CGFloat {
        get {
            return self.frame.origin.x
        }
        set {
            var selfFrame = self.frame
            selfFrame.origin.x = CGFloat(newValue)
            self.frame = selfFrame
        }
    }

    @discardableResult
    @objc func x(_ value: CGFloat) -> Self{
        x = value
        return self
    }

    @objc var y : CGFloat {
        get {
            return self.frame.origin.y
        }
        set {
            var selfFrame = self.frame
            selfFrame.origin.y = CGFloat(newValue)
            self.frame = selfFrame
        }
    }

    @discardableResult
    @objc func y(_ value: CGFloat) -> Self{
        y = value
        return self
    }

    @objc var width : CGFloat {
        get {
            return self.frame.size.width
        }
        set {
            var selfFrame = self.frame
            selfFrame.size.width = CGFloat(newValue)
            self.frame = selfFrame
        }
    }

    @discardableResult
    @objc func width(_ value: CGFloat) -> Self{
        width = value
        return self
    }

    @objc var height: CGFloat {
        get {
            return self.frame.size.height
        }
        set {
            var selfFrame = self.frame
            selfFrame.size.height = CGFloat(newValue)
            self.frame = selfFrame
        }
    }

    @discardableResult
    @objc func height(_ value: CGFloat) -> Self{
        height = value
        return self
    }

    @objc var maxX: CGFloat {
        get {
            return self.frame.size.width + self.frame.origin.x
        }
    }

    @objc var maxY: CGFloat {
        get {
            return self.frame.size.height + self.frame.origin.y
        }
    }

    @objc var size: CGSize {
        get {
            return self.frame.size
        }
        set {
            var selfFrame = self.frame
            selfFrame.size = newValue
            self.frame = selfFrame
        }
    }

    @discardableResult
    @objc func size(_ value: CGSize) -> Self{
        size = value
        return self
    }

    @objc var origin : CGPoint {
        get {
            return self.frame.origin
        }
        set {
            var selfFrame = self.frame
            selfFrame.origin = newValue
            self.frame = selfFrame
        }
    }

    @discardableResult
    @objc func origin(_ value: CGPoint) -> Self{
        origin = value
        return self
    }

    @objc var centerX: CGFloat {
        get {
            return self.center.x
        }
        set {
            var center = self.center
            center.x = newValue
            self.center = center
        }
    }

    @discardableResult
    @objc func centerX(_ value: CGFloat) -> Self{
        centerX = value
        return self
    }

    @objc var centerY: CGFloat {
        get {
            return self.center.y
        }
        set {
            var center = self.center
            center.y = newValue
            self.center = center
        }
    }

    @discardableResult
    @objc func centerY(_ value: CGFloat) -> Self{
        centerY = value
        return self
    }

    @objc var borderColor: UIColor {
        get {
            return UIColor.init(cgColor: self.layer.borderColor!)
        }
        set {
            self.layer.borderColor = newValue.cgColor
        }
    }

    @discardableResult
    @objc func borderColor(_ value: UIColor) -> Self{
        borderColor = value
        return self
    }

    @objc var borderWidth: CGFloat {
        get {
            return self.layer.borderWidth
        }
        set {
            self.layer.borderWidth = newValue
        }
    }

    @discardableResult
    @objc func borderWidth(_ value: CGFloat) -> Self{
        borderWidth = value
        return self
    }

    @objc var cornerRadius: CGFloat {
        get {
            return self.layer.cornerRadius
        }
        set {
            self.layer.masksToBounds = true
            self.layer.cornerRadius = newValue
        }
    }

    @discardableResult
    @objc func cornerRadius(_ value: CGFloat) -> Self{
        cornerRadius = value
        return self
    }
    
    @objc var masksToBounds: Bool{
        get{
            return self.layer.masksToBounds
        }
        set{
            self.layer.masksToBounds = newValue
        }
    }
    
    @discardableResult
    @objc func masksToBounds(_ value: Bool) -> Self{
        masksToBounds = value
        return self
    }

    @discardableResult
    func border(width: CGFloat = 0.5, color: UIColor = UIColor.gray, radius: CGFloat? = nil) -> Self {
        self.borderColor = color
        self.borderWidth = width
        guard let radius = radius else { return self}
        self.cornerRadius = radius
        return self
    }

    @discardableResult
    @objc func isUserInteractionEnabled(_ enable: Bool) -> Self{
        self.isUserInteractionEnabled = enable
        return self
    }

    @discardableResult
    @objc func isHidden(_ enable: Bool) -> Self{
        self.isHidden = enable
        return self
    }

    /// 删除所有的字窗体
    @objc func removeAllSubViews(){
        while self.subviews.count > 0 {
            self.subviews.last?.removeFromSuperview()
        }
    }

    /// 删除本窗体中 选中的子窗体
    /// - Parameter subViews: 想要删除的窗体
    @objc func remove(subViews:[UIView]) -> Void {
        for subView in subViews {
            subView.removeFromSuperview()
        }
    }

    /// 找到本窗体中的
    func findSubView<T: UIView>(_ Class: T.Type, resursion:Bool) -> T? {
            for subview in self.subviews {
                if subview is T {
                    return subview as? T
                }
            }
        return nil
    }


    /// 查找当前View是否包含view
    /// - Parameter view: 需要查找的view
    @objc func isHave(view: UIView) -> Bool{
        return self.isHave(view: view, in: self)
    }

    @objc private func isHave(view: UIView, in superView: UIView) -> Bool{
        guard superView.subviews.count > 0  else { return false }
        for subView in superView.subviews {
            if subView == view { return true }
            if self.isHave(view: view, in: subView){
                return true
            }
        }
        return false
    }

    /// 渐变层
    private(set) var gradientLayer: CAGradientLayer?{
        set{
            let key: UnsafeRawPointer! = UnsafeRawPointer.init(bitPattern: "gradientLayer".hashValue)
            objc_setAssociatedObject(self, key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get{
            let key: UnsafeRawPointer! = UnsafeRawPointer.init(bitPattern: "gradientLayer".hashValue)
            let obj = objc_getAssociatedObject(self, key)
            return obj as? CAGradientLayer
        }
    }

    /// 添加一个渐变层  从startPoint->endPint   起始点x,y 在 0-1 之间
    @objc func addGradientLayer(form fColor: UIColor,to toColor: UIColor,start startPoint: CGPoint, end endPint:CGPoint){
        if self.gradientLayer != nil {
            self.gradientLayer?.removeFromSuperlayer()
        }
        self.removeObserver(keyPaths: ["frame","bounds"], key: "gradientLayer")
        self.gradientLayer = CAGradientLayer.init()
        self.gradientLayer?.frame = self.bounds
        self.gradientLayer?.colors = [fColor.cgColor,toColor.cgColor]
        self.gradientLayer?.startPoint = startPoint
        self.gradientLayer?.endPoint = endPint
        self.gradientLayer?.locations = [0,1]

        self.layer.insertSublayer(self.gradientLayer!, at: 0)
        self.addObservers(keyPaths: ["frame","bounds"], key: "gradientLayer") {[weak self] value in
            guard let `self` = self else { return }
            switch value.keyPath {
                case "frame","bounds":
                    if let gradientLayer = self.gradientLayer{
                        gradientLayer.frame = self.bounds
                    }
                    break
                default: break
            }
        }
    }
    
    /// 添加一个渐变层  从右边->左
    @objc func addGradientLayer(form fColor: UIColor,to toColor: UIColor){
        if self.gradientLayer != nil {
            self.gradientLayer?.removeFromSuperlayer()
        }
        self.removeObserver(keyPaths: ["frame","bounds"], key: "gradientLayer")
        self.gradientLayer = CAGradientLayer.init()
        self.gradientLayer?.frame = self.bounds
        self.gradientLayer?.colors = [fColor.cgColor,toColor.cgColor]
        self.gradientLayer?.startPoint = CGPoint(x: 0, y: 0.5)
        self.gradientLayer?.endPoint = CGPoint(x: 1, y: 0.5)
        self.gradientLayer?.locations = [0,1]

        self.layer.insertSublayer(self.gradientLayer!, at: 0)
        self.addObservers(keyPaths: ["frame","bounds"],key: "gradientLayer") {[weak self] value in
            guard let `self` = self else { return }
            switch value.keyPath {
                case "frame","bounds":
                    if let gradientLayer = self.gradientLayer{
                        gradientLayer.frame = self.bounds
                    }
                    break
                default: break
            }
        }
    }

    @discardableResult
    @objc func addLine(frame:CGRect, color:UIColor) -> UIView {
        let lineView = UIView.init(frame:frame)
        lineView.backgroundColor = color
        self.addSubview(lineView)
        return lineView
    }

    @discardableResult
    @objc func addLine(_ color:UIColor = DefaultborderColor, layout:((_ view: UIView) -> ())) -> UIView {
        let lineView = UIView.init()
        lineView.backgroundColor = color
        self.addSubview(lineView)
        layout(lineView)
        return lineView
    }
    
    @discardableResult
    @objc func addLine(size:CGFloat,alignment:UIViewLineAlignment,color:UIColor) -> UIView{
        var lineframe = CGRect.init()
        switch alignment {
        case .Top:
            lineframe.size.width = self.width
            lineframe.size.height = size
        case .Left:
            lineframe.size.width = size
            lineframe.size.height = self.height
        case .Right:
            lineframe.origin.x = self.width - size
            lineframe.size.width = size
            lineframe.size.height = self.height
        default:
            lineframe.origin.y = self.height - size
            lineframe.size.width = self.width
            lineframe.size.height = size
        }
        return addLine(frame: lineframe, color: color)
    }

    //MARK: - 部分圆角
    private(set) var corners: UIRectCorner {
        set{
            objc_set(key: "corners", newValue)
        }
        get{
            return objc_get(key: "corners", UIRectCorner.self) ?? .allCorners
        }
    }
    private(set) var radii: CGFloat{
        set{
            objc_set(key: "radii", newValue)
        }
        get{
            return objc_get(key: "radii", CGFloat.self) ?? 0
        }
    }
    private(set) var roundCornerLayer: CAShapeLayer?{
        set{
            objc_set(key: "roundCornerLayer", newValue)
        }
        get{
            return objc_get(key: "roundCornerLayer", CAShapeLayer.self)
        }
    }
    /// 部分圆角
    ///
    /// - Parameters:
    ///   - corners: 需要实现为圆角的角，可传入多个
    ///   - radii: 圆角半径
    @discardableResult
    @objc func addRound(_ corners: UIRectCorner, radii: CGFloat) -> Self{
        self.removeObserver(keyPaths: ["frame","bounds"], key: "roundCornerLayer")
        self.roundCornerLayer?.removeFromSuperlayer()
        self.corners = corners
        self.radii = radii
        let maskPath = UIBezierPath(roundedRect: self.bounds,
                                    byRoundingCorners: self.corners,
                                    cornerRadii: CGSize(width: self.radii, height: self.radii))
        self.roundCornerLayer = CAShapeLayer()
        self.roundCornerLayer?.frame = self.bounds
        self.roundCornerLayer?.path = maskPath.cgPath
        self.layer.mask = self.roundCornerLayer
        self.addObservers(keyPaths: ["frame","bounds"] ,key: "roundCornerLayer") {[weak self] value in
            guard let `self` = self, let roundLayer = self.roundCornerLayer else { return }
            switch value.keyPath {
                case "frame","bounds":
                    let maskPath = UIBezierPath(roundedRect: self.bounds,
                                                byRoundingCorners: self.corners,
                                                cornerRadii: CGSize(width: self.radii, height: self.radii))
                    roundLayer.frame = self.bounds
                    roundLayer.path = maskPath.cgPath
                    break
                default: break
            }
        }
        return self
    }
}

/// 任意圆角的View
@objcMembers open class RoundCornerView: UIView {
    public override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required public init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    public init(round corners: UIRectCorner, radii: CGFloat) {
        super.init(frame: CGRect.zero)
//        self.corner(byRoundingCorners: corners, radii: radii)
        self.addRound(corners, radii: radii)
    }

    deinit {
        self.remoAllObservers()
    }
    
//    override public func layoutSubviews() {
//        super.layoutSubviews()
//        if self.roundCornerLayer != nil {
//            let maskPath = UIBezierPath(roundedRect: self.bounds,
//                                        byRoundingCorners: self.corners,
//                                        cornerRadii: CGSize(width: self.radii, height: self.radii))
//            self.roundCornerLayer?.frame = self.bounds
//            self.roundCornerLayer?.path = maskPath.cgPath
////            self.layer.mask = self.roundCornerLayer
//        }
//    }
//    //MARK: - 部分圆角
//    /// 部分圆角
//    ///
//    /// - Parameters:
//    ///   - corners: 需要实现为圆角的角，可传入多个
//    ///   - radii: 圆角半径
//    public var roundCornerLayer : CAShapeLayer?
//    public var corners : UIRectCorner = .allCorners
//    public var radii : CGFloat = 0
//    public func corner(byRoundingCorners corners: UIRectCorner, radii: CGFloat) {
//        self.corners = corners
//        self.radii = radii
//        let maskPath = UIBezierPath(roundedRect: self.bounds,
//                                    byRoundingCorners: self.corners,
//                                    cornerRadii: CGSize(width: self.radii, height: self.radii))
//        self.roundCornerLayer = CAShapeLayer()
//        self.roundCornerLayer?.frame = self.bounds
//        self.roundCornerLayer?.path = maskPath.cgPath
//        self.layer.mask = self.roundCornerLayer
//    }
}

public extension CGRect{
    var x : CGFloat {
        get {
            return self.origin.x
        }
        set {
            self.origin.x = newValue
        }
    }
    var y : CGFloat {
        get {
            return self.origin.y
        }
        set {
            self.origin.y = newValue
        }
    }
    var zz_width : CGFloat {
        get {
            return self.size.width
        }
        set {
            self.size.width = newValue
        }
    }
    var zz_height : CGFloat {
        get {
            return self.size.height
        }
        set {
            self.size.height = newValue
        }
    }
}
